home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i050: Screen-oriented rolodex program, Part02/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Dave Ihnat <ihnp4!homebru!ignatz>
- Posting-number: Volume 13, Issue 50
- Archive-name: rolodex/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 4)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f './datadef.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./datadef.h'\"
- else
- echo shar: Extracting \"'./datadef.h'\" \(2603 characters\)
- sed "s/^X//" >'./datadef.h' <<'END_OF_FILE'
- X/* datadef.h */
- X#define ABORTSTRING "\\"
- X#define ABORTCHAR '\\'
- X
- X#define MAXMATCHES 17
- X
- X#define N_BASIC_FIELDS 8
- X#define OTHER -1
- X
- X#ifdef UNIX
- X#ifdef SYS5
- X#define rindex(a,b) strrchr(a,b)
- X#define index(a,b) strchr(a,b)
- X#endif
- X#ifdef BSD
- X#include <string.h>
- X#endif
- X#endif
- X
- Xtypedef enum Basic_Field {
- X
- X R_NAME = 0, R_WORK_PHONE, R_HOME_PHONE, R_COMPANY, R_WORK_ADDRESS,
- X R_HOME_ADDRESS, R_REMARKS, R_UPDATED
- X
- X };
- X
- Xextern char *Field_Names[];
- X
- X/* A Rolodex entry */
- X
- Xtypedef struct {
- X
- X char *basicfields[N_BASIC_FIELDS];
- X int n_others;
- X char **other_fields;
- X
- X } Rolo_Entry, *Ptr_Rolo_Entry;
- X
- X
- X#define get_basic_rolo_field(n,x) (((x) -> basicfields)[(n)])
- X#define get_n_others(x) ((x) -> n_others)
- X#define get_other_field(n,x) (((x) -> other_fields)[n])
- X
- X#define set_basic_rolo_field(n,x,s) (((x) -> basicfields[(n)]) = (s))
- X#define set_n_others(x,n) (((x) -> n_others) = (n))
- X#define incr_n_others(x) (((x) -> n_others)++)
- X#define set_other_field(n,x,s) ((((x) -> other_fields)[n]) = (s))
- X
- Xtypedef struct link {
- X
- X#ifndef VMS
- X Ptr_Rolo_Entry entry;
- X#else
- X Ptr_Rolo_Entry ventry;
- X#endif
- X int matched;
- X struct link *prev;
- X#ifndef M_V7
- X struct link *next;
- X#else
- X struct link *lnext;
- X#endif
- X
- X } Rolo_List, *Ptr_Rolo_List;
- X
- X
- X#ifndef M_V7
- X#define get_next_link(x) ((x) -> next)
- X#else
- X#define get_next_link(x) ((x) -> lnext)
- X#endif
- X#define get_prev_link(x) ((x) -> prev)
- X#ifndef VMS
- X#define get_entry(x) ((x) -> entry)
- X#else
- X#define get_entry(x) ((x) -> ventry)
- X#endif
- X#define get_matched(x) ((x) -> matched)
- X
- X#ifndef M_V7
- X#define set_next_link(x,y) (((x) -> next) = (y))
- X#else
- X#define set_next_link(x,y) (((x) -> lnext) = (y))
- X#endif
- X#define set_prev_link(x,y) (((x) -> prev) = (y))
- X#ifndef VMS
- X#define set_entry(x,y) (((x) -> entry) = (y))
- X#else
- X#define set_entry(x,y) (((x) -> ventry) = (y))
- X#endif
- X#define set_matched(x) (((x) -> matched) = 1)
- X#define unset_matched(x) (((x) -> matched) = 0);
- X
- Xextern Ptr_Rolo_List Begin_Rlist;
- Xextern Ptr_Rolo_List End_Rlist;
- X
- X#define MAXLINELEN 80
- X#define DIRPATHLEN 100
- X
- Xextern int changed;
- Xextern int name_changed;
- Xextern int reorder_file;
- Xextern int rololocked;
- Xextern int read_only;
- X
- Xextern char *rolo_emalloc();
- Xextern char *malloc();
- Xextern Ptr_Rolo_List new_link_with_entry();
- Xextern char *copystr();
- Xextern int compare_links();
- Xextern char *timestring();
- Xextern char *homedir(), *libdir();
- Xextern char *getenv();
- Xextern char *ctime();
- Xextern char *select_search_string();
- Xextern int in_search_mode;
- X
- X/*
- X * This structure allows documentation and internal access to help files
- X */
- Xextern char *hlpfiles[];
- END_OF_FILE
- if test 2603 -ne `wc -c <'./datadef.h'`; then
- echo shar: \"'./datadef.h'\" unpacked with wrong size!
- fi
- # end of './datadef.h'
- fi
- if test -f './options.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./options.c'\"
- else
- echo shar: Extracting \"'./options.c'\" \(7034 characters\)
- sed "s/^X//" >'./options.c' <<'END_OF_FILE'
- X/* options.c */
- X#ifdef UNIX
- X#include <sys/types.h>
- X#include <time.h>
- X#ifdef BSD
- X#include <sys/file.h>
- X#include <sgtty.h>
- X#else
- X#include <fcntl.h>
- X#endif
- X#endif
- X
- X#ifdef VMS
- X#include <types.h>
- X#include <time.h>
- X#include <file.h>
- X#endif
- X
- X#ifdef MSDOS
- X#include <time.h>
- X#include <fcntl.h>
- X#endif
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#include <signal.h>
- X
- X#ifdef TMC
- X#include <ctools.h>
- X#else
- X#include "ctools.h"
- X#endif
- X#include "args.h"
- X#include "menu.h"
- X#include "mem.h"
- X
- X#include "rolofilz.h"
- X#include "rolodefs.h"
- X#include "datadef.h"
- X#include "choices.h"
- X
- X
- Xprint_short ()
- X
- X/* print the names and phone numbers of everyone in the rolodex. */
- X
- X{
- X
- X Ptr_Rolo_List rptr;
- X Ptr_Rolo_Entry lentry;
- X
- X rptr = Begin_Rlist;
- X if (rptr == 0) {
- X fprintf(stderr,"No entries to print out...\n");
- X return;
- X }
- X
- X fprintf (
- X stdout,
- X "\nNAME WORK PHONE HOME PHONE"
- X );
- X fprintf (
- X stdout,
- X "\n---- ---------- ----------\n\n\n"
- X );
- X
- X while (rptr != 0) {
- X lentry = get_entry(rptr);
- X fprintf (
- X stdout,
- X "%-25s %-25s %-25s\n",
- X get_basic_rolo_field((int) R_NAME,lentry),
- X get_basic_rolo_field((int) R_WORK_PHONE,lentry),
- X get_basic_rolo_field((int) R_HOME_PHONE,lentry)
- X );
- X rptr = get_next_link(rptr);
- X }
- X
- X }
- X
- X
- Xperson_match (person,lentry) char *person; Ptr_Rolo_Entry lentry;
- X
- X/* Match against a rolodex entry's Name and Company fields. */
- X/* Thus if I say 'rolo CCA' I will find people who work at CCA. */
- X/* This is good because sometimes you will forget a name but remember */
- X/* the company the person works for. */
- X
- X{
- X char *name, *company;
- X int len;
- X len = strlen(person);
- X name = get_basic_rolo_field((int) R_NAME,lentry);
- X company = get_basic_rolo_field((int) R_COMPANY,lentry);
- X if (strncsearch(name,strlen(name),person,len)) return(1);
- X if (strncsearch(company,strlen(company),person,len)) return(1);
- X return(0);
- X}
- X
- X
- Xint find_all_person_matches (person) char *person;
- X
- X{
- X Ptr_Rolo_List rptr = Begin_Rlist;
- X int count = 0;
- X while (rptr != 0) {
- X unset_matched(rptr);
- X if (person_match(person,get_entry(rptr))) {
- X set_matched(rptr);
- X count++;
- X }
- X rptr = get_next_link(rptr);
- X }
- X return(count);
- X}
- X
- X
- Xlook_for_person (person) char *person;
- X
- X/* search against Name and Company over the rolodex. If a match is found */
- X/* display the entry and give the user a choice of what to do next. */
- X
- X{
- X Ptr_Rolo_List rptr;
- X int found = 0,result,nmatches;
- X static displayed_menu = 0;
- X char *response;
- X
- X rptr = Begin_Rlist;
- X while (rptr != 0) {
- X if (person_match(person,get_entry(rptr))) {
- X clear_the_screen();
- X display_entry(get_entry(rptr));
- X if (!found) {
- X nmatches = find_all_person_matches(person);
- X if (nmatches > 1) {
- X printf (
- X "There are %d other entries which match '%s'\n\n",
- X nmatches - 1, person
- X );
- X }
- X }
- X found = 1;
- X try_again :
- X if (!displayed_menu) cathelpfile(POPTIONMENU,(char *)NULL,0);
- X displayed_menu = 1;
- X menu_match (
- X &result,
- X &response,
- X "Select option (? for help): ",
- X 0,1,1,1,6,
- X "Continue",P_CONTINUE,
- X "",P_CONTINUE,
- X "Next",P_NEXT_PERSON,
- X "\\",P_ABORT,
- X "Help",P_HELP,
- X "?",P_HELP
- X );
- X switch (result) {
- X case P_CONTINUE :
- X break;
- X case P_NEXT_PERSON :
- X return(0);
- X /* break; */
- X case P_ABORT :
- X roloexit(0);
- X break;
- X case P_HELP :
- X cathelpfile(POPTIONSHELP,"person search options",1);
- X goto try_again;
- X default :
- X fprintf(stderr,"Impossible return from menu_match\n");
- X exit(-1);
- X }
- X }
- X rptr = get_next_link(rptr);
- X }
- X if (!found) {
- X fprintf(stderr,"\nNo entry found for '%s'\n\n",person);
- X sleep(2);
- X }
- X else {
- X printf("No further matches for '%s'\n",person);
- X sleep(2);
- X }
- X return(0);
- X}
- X
- X
- Xprint_people ()
- X
- X{
- X int index;
- X char *person;
- X index = 1;
- X while (T) {
- X if (0 == (person = non_option_arg(index++))) break;
- X look_for_person(person);
- X }
- X}
- X
- X
- Xinteractive_rolo ()
- X
- X/* Top level of the iteractive rolodex. This code is just a big switch */
- X/* which passes responsibility off to various routines in 'operatns.c' */
- X/* and 'update.c' */
- X
- X{
- X
- X int result,rval,field_index;
- X char *response,*field_name,*search_string;
- X
- X fprintf(stdout,"\n\nTMC ROLODEX, Version %s\n\n\n",VERSION);
- X
- X while (1) {
- X
- X cathelpfile(MAINMENU,(char *)NULL,0);
- X rval = menu_match (
- X &result,
- X &response,
- X "Select option (? for help): ",
- X 0,1,0,1,7,
- X "+",M_ADD,
- X "%",M_PERUSE,
- X "\\",M_EXIT,
- X "?",M_HELP,
- X "*",M_SAVE,
- X "$",M_SEARCH_BY_OTHER,
- X "!",M_PRINT_TO_LASER_PRINTER
- X );
- X
- X switch (rval) {
- X
- X case MENU_AMBIGUOUS :
- X case MENU_ERROR :
- X fprintf(stderr,"Impossible return 1 from main menu_match\n");
- X exit(-1);
- X break;
- X
- X case MENU_NO_MATCH :
- X response = copystr(response);
- X rolo_search_mode((int) R_NAME,Field_Names[(int) R_NAME],response);
- X break;
- X
- X case MENU_MATCH :
- X
- X switch (result) {
- X case M_ADD :
- X rolo_add();
- X break;
- X case M_SEARCH_BY_OTHER :
- X if ((-1 == select_field_to_search_by(&field_index,&field_name)) ||
- X (0 == (search_string = select_search_string()))) {
- X break;
- X }
- X rolo_search_mode(field_index,field_name,search_string);
- X break;
- X case M_PRINT_TO_LASER_PRINTER :
- X /* fprintf(stderr,"Not implemented\n"); */
- X pretty_print();
- X sleep(1);
- X break;
- X case M_PERUSE :
- X rolo_peruse_mode(Begin_Rlist);
- X break;
- X case M_EXIT :
- X save_and_exit(0);
- X break;
- X case M_SAVE :
- X if (changed) {
- X save_to_disk();
- X sleep(1);
- X }
- X else {
- X printf("No changes to be saved...\n");
- X sleep(2);
- X }
- X break;
- X case M_HELP :
- X cathelpfile(MOPTIONHELP,"top level menu",1);
- X any_char_to_continue();
- X break;
- X default :
- X fprintf(stderr,"Impossible result from menu_match...\n");
- X save_and_exit(-1);
- X }
- X break;
- X
- X case MENU_EOF :
- X user_eof();
- X break;
- X
- X default :
- X fprintf(stderr,"Impossible return 2 from menu_match\n");
- X save_and_exit(-1);
- X
- X }
- X
- X clear_the_screen();
- X
- X }
- X
- X}
- END_OF_FILE
- if test 7034 -ne `wc -c <'./options.c'`; then
- echo shar: \"'./options.c'\" unpacked with wrong size!
- fi
- # end of './options.c'
- fi
- if test -f './rlist.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./rlist.c'\"
- else
- echo shar: Extracting \"'./rlist.c'\" \(2570 characters\)
- sed "s/^X//" >'./rlist.c' <<'END_OF_FILE'
- X/* rlist.c */
- X#include "datadef.h"
- X
- X
- Xint rlength (rlist) Ptr_Rolo_List rlist;
- X{
- X return((rlist == 0) ? 0 : 1 + rlength(get_next_link(rlist)));
- X}
- X
- X
- XPtr_Rolo_List new_link_with_entry ()
- X{
- X Ptr_Rolo_List newlink;
- X Ptr_Rolo_Entry newentry;
- X newlink = (Ptr_Rolo_List) rolo_emalloc(sizeof(Rolo_List));
- X unset_matched(newlink);
- X newentry = (Ptr_Rolo_Entry) rolo_emalloc(sizeof(Rolo_Entry));
- X set_n_others(newentry,0);
- X newentry -> other_fields = 0;
- X set_entry(newlink,newentry);
- X return(newlink);
- X}
- X
- X
- Xrolo_insert (link,compare) Ptr_Rolo_List link; int (*compare)();
- X
- X{
- X Ptr_Rolo_List rptr;
- X
- X if (Begin_Rlist == 0) {
- X Begin_Rlist = link;
- X End_Rlist = link;
- X set_prev_link(link,0);
- X set_next_link(link,0);
- X return;
- X }
- X
- X /* find the element it goes before, alphabetically, and insert it */
- X
- X rptr = Begin_Rlist;
- X while (rptr != 0) {
- X if (1 == (*compare)(rptr,link)) {
- X set_prev_link(link,get_prev_link(rptr));
- X set_next_link(link,rptr);
- X if (get_prev_link(rptr) != 0)
- X set_next_link(get_prev_link(rptr),link);
- X else
- X Begin_Rlist = link;
- X set_prev_link(rptr,link);
- X return;
- X }
- X rptr = get_next_link(rptr);
- X }
- X
- X /* it goes at the end */
- X
- X set_next_link(End_Rlist,link);
- X set_prev_link(link,End_Rlist);
- X set_next_link(link,0);
- X End_Rlist = link;
- X return;
- X
- X}
- X
- X
- Xrolo_delete (link) Ptr_Rolo_List link;
- X
- X{
- X if (read_only)
- X {
- X printf("Readonly mode: Cannot delete entries.\n");
- X sleep(2);
- X return(1);
- X }
- X
- X if (get_next_link(link) == 0 && get_prev_link(link) == 0) {
- X Begin_Rlist = 0;
- X End_Rlist = 0;
- X return(0);
- X }
- X
- X if (get_prev_link(link) == 0) {
- X Begin_Rlist = get_next_link(link);
- X set_prev_link(Begin_Rlist,0);
- X return(0);
- X }
- X
- X if (get_next_link(link) == 0) {
- X End_Rlist = get_prev_link(link);
- X set_next_link(End_Rlist,0);
- X return(0);
- X }
- X
- X set_next_link(get_prev_link(link),get_next_link(link));
- X set_prev_link(get_next_link(link),get_prev_link(link));
- X return(0);
- X
- X}
- X
- X
- Xcompare_links (l1,l2) Ptr_Rolo_List l1,l2;
- X
- X{
- X Ptr_Rolo_Entry e1,e2;
- X char *n1,*n2;
- X e1 = get_entry(l1);
- X e2 = get_entry(l2);
- X n1 = get_basic_rolo_field((int) R_NAME,e1);
- X n2 = get_basic_rolo_field((int) R_NAME,e2);
- X return(nocase_compare(n1,strlen(n1),n2,strlen(n2)));
- X}
- X
- X
- Xrolo_reorder ()
- X{
- X Ptr_Rolo_List rptr,oldlink;
- X rptr = Begin_Rlist;
- X Begin_Rlist = 0;
- X while (rptr != 0) {
- X oldlink = get_next_link(rptr);
- X rolo_insert(rptr,compare_links);
- X rptr = oldlink;
- X }
- X}
- END_OF_FILE
- if test 2570 -ne `wc -c <'./rlist.c'`; then
- echo shar: \"'./rlist.c'\" unpacked with wrong size!
- fi
- # end of './rlist.c'
- fi
- if test -f './rolo.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./rolo.1'\"
- else
- echo shar: Extracting \"'./rolo.1'\" \(2616 characters\)
- sed "s/^X//" >'./rolo.1' <<'END_OF_FILE'
- X.TH ROLO 1 "18 November 1984"
- X.UC 4
- X.SH NAME
- Xrolo \- use an online rolodex, containing information about people.
- X.SH SYNOPSIS
- X.B rolo
- X[ name1 name2 ... \-u otheruser \-s \-l \-r ]
- X.SH DESCRIPTION
- XBy default
- X.I rolo
- Xreads in a rolodex data file from the user's home directory, prints
- Xout a menu of choices, and lets the user scan, update, delete and add to
- Xhis personal database of people. If no rolodex database exists one
- Xis created.
- X.I rolo
- Xchecks to see that the rolodex database is not already in use.
- X.PP
- XThe command line options are:
- X.TP
- X.B \-u otheruser
- XUses the rolodex database in the 'otheruser' home directory. This may
- Xnot be possible if the directory or the database is read or write protected.
- XFor VMS or DOS, it will simply use files found in directory 'otheruser';
- Xthis need not be the home directory.
- X.TP
- X.B \-s
- XPrints people's names, work phone numbers and home phone numbers in a nice
- Xformat to standard output.
- X.TP
- X.B \-l
- XNormally the rolodex database is locked when being used. This option
- Xunlocks the database as soon as it is read in. The \-s option implies this.
- X.TP
- X.B \-r
- XReadonly mode. Assuming that the files may be read, this allows readonly
- Xaccess to the database.
- X.PP
- XInvoking
- X.I rolo
- Xfollowed by a list of names causes
- X.I
- Xrolo
- Xto search the database for all people whose names or company
- Xaffiliations contain any of the name arguments as substrings. All the
- Xinformation about each person is printed to standard output, the program
- Xpausing after each record is printed. Using this feature causes the
- Xdatabase to become unlocked, since this is a read-only mode.
- X.PP
- XExtensive help is available on-line. Typing '?' or 'help' will generally
- Xprint a help file for you.
- X.SH FILES
- X/usr/local/src/rolo for the source.
- X.PP
- X/usr/local/lib/rolo for help files.
- X.PP
- X/usr/local/bin/rolo the executable image.
- X.PP
- X.PP
- X.SH AUTHOR
- XPeter Webb wrote the first rolodex program.
- X.PP
- XJP Massar revised and then complete rewrote this older version.
- XNet address: massar@think.com, ihnp4!think!massar.
- X.PP
- XDave Ihnat revised the program to work for VMS and MS/PC-DOS; and to support
- Xthe readonly command-line flag. Numerous other minor enhancements, bug fixes,
- Xdelinting, etc.
- XNet address: ihnp4!homebru!ignatz.
- X
- X.PP
- XSteve Steiner implemented the pretty-print option, and with Dave Ihnat hammered
- Xout the current version which runs on VMS, AT&T Unix Sys III/V, BSD 4.x Unix,
- Xand MS/PC-DOS under Microsoft C and Turbo-C. (*whew!*)
- XNet address: ihnp4!aicchi!steiner.
- X.SH BUGS
- XThere is no way to keep certain entries private.
- X.PP
- XYou can't get a short summary of only a subset of people.
- END_OF_FILE
- if test 2616 -ne `wc -c <'./rolo.1'`; then
- echo shar: \"'./rolo.1'\" unpacked with wrong size!
- fi
- # end of './rolo.1'
- fi
- if test -f './search.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./search.c'\"
- else
- echo shar: Extracting \"'./search.c'\" \(9196 characters\)
- sed "s/^X//" >'./search.c' <<'END_OF_FILE'
- X/* search.c */
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#ifdef TMC
- X#include <ctools.h>
- X#else
- X#include "ctools.h"
- X#endif
- X#include "args.h"
- X#include "menu.h"
- X#include "mem.h"
- X
- X#include "rolofilz.h"
- X#include "rolodefs.h"
- X#include "datadef.h"
- X#include "choices.h"
- X
- X
- Xchar *select_search_string ()
- X
- X/* returns 0 if user wants to quit, otherwise returns a user-provided string */
- X
- X{
- X int rval;
- X char *response;
- X rval = rolo_menu_data_help_or_abort (
- X "Enter string to search for: ",
- X SEARCHSTRINGHELP,
- X "string to search for",
- X &response
- X );
- X switch (rval) {
- X case MENU_ABORT :
- X return(0);
- X /* break; */
- X case MENU_DATA :
- X return(copystr(response));
- X /* break; */
- X }
- X
- X return(0);
- X}
- X
- X
- Xselect_field_to_search_by (ptr_index,ptr_name) int *ptr_index; char **ptr_name;
- X
- X/* returns -1 if the user wishes to abort, otherwise returns 0. */
- X/* if the user wishes to search by a user-defined field, *ptr_index is OTHER */
- X/* and *ptr_name is the user-provided name of the field. */
- X
- X{
- X char *response;
- X int nchoices = N_BASIC_FIELDS;
- X int field_index,rval;
- X
- X redo :
- X
- X /* list out each basic field that the user can search by. The user is */
- X /* also given an option to search by a user-provided field. At the */
- X /* moment you cannot search by 'Date Updated' */
- X
- X display_field_names();
- X
- X /* reask : */
- X
- X rval = rolo_menu_number_help_or_abort (
- X "Number of item to search by? ",
- X 1,nchoices,&field_index
- X );
- X
- X switch (rval) {
- X
- X case MENU_ABORT :
- X return(-1);
- X /* break; */
- X
- X case MENU_HELP :
- X cathelpfile(FIELDSEARCHHELP,"entering search field",1);
- X any_char_to_continue();
- X goto redo;
- X /* break; */
- X
- X case MENU_DATA :
- X
- X if (field_index != nchoices) {
- X *ptr_index = field_index - 1;
- X *ptr_name = copystr(Field_Names[*ptr_index]);
- X return(0);
- X }
- X
- X /* the user wants to search by a user-specified field */
- X
- X else {
- X
- X /* reask2 : */
- X
- X rval = rolo_menu_data_help_or_abort (
- X "Name of user-defined field? ",
- X USERFIELDHELP,
- X "name of user field to search by",
- X &response
- X );
- X switch (rval) {
- X case MENU_ABORT :
- X return(-1);
- X /* break; */
- X case MENU_DATA :
- X *ptr_index = OTHER;
- X *ptr_name = copystr(response);
- X return(0);
- X /* break; */
- X }
- X }
- X break;
- X }
- X return(0);
- X}
- X
- X
- Xmatch_by_name_or_company (search_string,sslen) char *search_string; int sslen;
- X
- X{
- X char *name,*company;
- X Ptr_Rolo_Entry lentry;
- X Ptr_Rolo_List rlist;
- X int count = 0;
- X
- X rlist = Begin_Rlist;
- X while (rlist != 0) {
- X lentry = get_entry(rlist);
- X name = get_basic_rolo_field((int) R_NAME,lentry);
- X company = get_basic_rolo_field((int) R_COMPANY,lentry);
- X if (strncsearch(name,strlen(name),search_string,sslen) ||
- X strncsearch(company,strlen(company),search_string,sslen)) {
- X set_matched(rlist);
- X count++;
- X }
- X }
- X return(count);
- X
- X}
- X
- X
- Xmatch_link (rlink,field_index,field_name,fnlen,search_string,sslen)
- X
- X /* if a match is present, sets the 'matched' field in the link, and */
- X /* returns 1, otherwise returns 0. */
- X
- X Ptr_Rolo_List rlink;
- X int field_index;
- X char *field_name;
- X int fnlen;
- X char *search_string;
- X int sslen;
- X
- X{
- X Ptr_Rolo_Entry lentry;
- X char *field;
- X char name[100];
- X int j;
- X
- X lentry = get_entry(rlink);
- X
- X if (field_index == OTHER) {
- X for (j = 0; j < get_n_others(lentry); j++) {
- X field = get_other_field(j,lentry);
- X while (*field != ':') *field++;
- X *field = '\0';
- X remove_excess_blanks(name,get_other_field(j,lentry));
- X *field++ = ':';
- X if (0 != nocase_compare(name,strlen(name),field_name,fnlen)) {
- X continue;
- X }
- X if (strncsearch(field,strlen(field),search_string,sslen)) {
- X set_matched(rlink);
- X return(1);
- X }
- X }
- X return(0);
- X }
- X else {
- X field = get_basic_rolo_field(field_index,lentry);
- X if (strncsearch(field,strlen(field),search_string,sslen)) {
- X set_matched(rlink);
- X return(1);
- X }
- X return(0);
- X }
- X
- X}
- X
- X
- Xfind_all_matches (field_index,field_name,search_string,ptr_first_match)
- X
- X /* mark every entry in the rolodex which matches against the search_string */
- X /* If the search_string is a substring of the data in the given field then */
- X /* that is a match. Return the number of matches. If there are any */
- X /* matches *ptr_first_match will contain the first matching link. */
- X
- X int field_index;
- X char *field_name, *search_string;
- X Ptr_Rolo_List *ptr_first_match;
- X
- X{
- X char buffer[100];
- X int fnlen,sslen;
- X int count = 0;
- X Ptr_Rolo_List rlist = Begin_Rlist;
- X
- X remove_excess_blanks(buffer,field_name);
- X fnlen = strlen(buffer);
- X sslen = strlen(search_string);
- X
- X while (rlist != 0) {
- X unset_matched(rlist);
- X if (match_link(rlist,field_index,buffer,fnlen,search_string,sslen)) {
- X if (count++ == 0) *ptr_first_match = rlist;
- X }
- X rlist = get_next_link(rlist);
- X }
- X
- X return(count);
- X
- X}
- X
- X
- Xrolo_search_mode (field_index,field_name,search_string)
- X
- X int field_index;
- X char *field_name;
- X char *search_string;
- X
- X{
- X int rval,n,j,menuval,ival;
- X char *response;
- X Ptr_Rolo_List first_match,rmatch,rlist;
- X
- X /* mark every entry in the rolodex that satisfies the search criteria */
- X /* and return the number of items so marked. */
- X
- X in_search_mode = 1;
- X n = find_all_matches(field_index,field_name,search_string,&first_match);
- X
- X if (n == 0) {
- X printf (
- X "No match found for search string '%s' for field '%s'\n",
- X search_string,
- X field_name
- X );
- X sleep(2);
- X goto rtn;
- X }
- X
- X /* if the match is unique, just display the entry. */
- X
- X else if (n == 1) {
- X display_entry(get_entry(first_match));
- X switch (entry_action(first_match)) {
- X case E_CONTINUE :
- X printf("No further matches...\n");
- X sleep(2);
- X break;
- X default :
- X break;
- X }
- X goto rtn;
- X }
- X
- X /* if there are too many matches to itemize them on a single small */
- X /* screen, tell the user that there are lots of matches and suggest */
- X /* he specify a better search string, but give him the option of */
- X /* iterating through every match. */
- X
- X else if (n > MAXMATCHES) {
- X clear_the_screen();
- X printf("There are %d entries that match '%s' !\n",n,search_string);
- X printf("Type 'v' to view them one by one,\n");
- X printf("or '\\' to abort and enter a more specific search string: ");
- X rval = rolo_menu_data_help_or_abort (
- X "",MANYMATCHHELP,"many matching entries",&response
- X );
- X if (rval == MENU_ABORT) goto rtn;
- X display_list_of_entries(Begin_Rlist);
- X goto rtn;
- X }
- X
- X /* there are a small number of matching entries. List the name of each */
- X /* matching entry and let the user select which one he wants to view, */
- X /* or whether he wants to iterate through each matching entry. */
- X
- X else {
- X relist :
- X summarize_entry_list(Begin_Rlist,search_string);
- X cathelpfile(PICKENTRYMENU,(char *)NULL,0);
- X rval = menu_match (
- X &menuval,&response,
- X ": ",
- X 0,1,0,1,4,
- X "\\",S_ABORT,
- X "?",S_HELP,
- X "Help",S_HELP,
- X "",S_SCAN_ONE_BY_ONE
- X );
- X switch (rval) {
- X case MENU_MATCH :
- X switch (menuval) {
- X case S_HELP :
- X cathelpfile(PICKENTRYHELP,"selecting entry to view",1);
- X any_char_to_continue();
- X goto relist;
- X /* break; */
- X case S_ABORT :
- X goto rtn;
- X /* break; */
- X case S_SCAN_ONE_BY_ONE :
- X display_list_of_entries(Begin_Rlist);
- X goto rtn;
- X /* break; */
- X }
- X break;
- X
- X /* make sure the user entered a valid integer, ival */
- X /* if so, find the ivalth entry marked as matched in the rolodex */
- X /* and display it. */
- X
- X case MENU_NO_MATCH :
- X ival = str_to_pos_int(response,1,n);
- X if (ival < 0) {
- X printf("Not a valid number... Please try again\n");
- X sleep(2);
- X goto relist;
- X }
- X rlist = Begin_Rlist;
- X for (j = 0; j < ival; j++) {
- X while (rlist != 0) {
- X if (get_matched(rmatch = rlist)) break;
- X rlist = get_next_link(rlist);
- X }
- X if (rlist != 0) rlist = get_next_link(rlist);
- X }
- X display_entry(get_entry(rmatch));
- X switch (entry_action(rmatch)) {
- X case E_CONTINUE :
- X case E_PREV :
- X goto relist;
- X /* break; */
- X default :
- X goto rtn;
- X /* break; */
- X }
- X /* break; */
- X }
- X }
- X
- X rtn :
- X in_search_mode = 0;
- X
- X}
- END_OF_FILE
- if test 9196 -ne `wc -c <'./search.c'`; then
- echo shar: \"'./search.c'\" unpacked with wrong size!
- fi
- # end of './search.c'
- fi
- if test -f './toolsdir/args.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./toolsdir/args.c'\"
- else
- echo shar: Extracting \"'./toolsdir/args.c'\" \(9032 characters\)
- sed "s/^X//" >'./toolsdir/args.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "basics.h"
- X#include "args.h"
- X#include "sys5.h"
- X
- X/***************************************************************************/
- X/***************************************************************************/
- X
- X /***** COMMAND LINE ARGUMENT PARSER *****/
- X
- X/***************************************************************************/
- X/***************************************************************************/
- X
- X/* Author: JP Massar */
- X
- X/* parses command line arguments in argv under the following rules: */
- X/* any argument not beginning with '-' is treated as a unit. */
- X/* any argument beginning with a '-' must have the remaining characters */
- X/* be in the set {a-zA-Z}. Each character is considered a separate option. */
- X/* (Thus -abc is equivalent to -a -b -c). Non-dashed arguments are */
- X/* associated with the option that precedes them, e.g, 'cat -a foo -b bar' */
- X/* has foo associated with 'a' and bar associated with 'b'. A non-dashed */
- X/* argument preceding any option is not associated with any option. */
- X/* users can specify whether duplicate options are errors. */
- X
- X/* Non-dashed arguments are henceforth referred to as arguments, and */
- X/* dashed arguments are henceforth referred to as options. */
- X/* Arguments are ordered from left to right. */
- X
- X/* 5/8/87 - D. M. Ihnat. Modified for DOS/VMS to honor '/' as a separator.
- X*/
- X/* The following routines are available to users: */
- X
- X/* get_args() called to parse argv. Detects syntactic errors */
- X/* any_option_present() are any options present in the command line? */
- X/* option_present() is an option present? */
- X/* option_arg() returns an argument associated with an option */
- X/* non_option_arg() returns an argument not associated with any option */
- X/* non_dash_arg() returns an argument */
- X/* n_option_args() returns number of args associated with an option */
- X/* n_non_option_args() rtns number of args not associated with any option */
- X/* n_non_dash_args() returns number of arguments. */
- X/* check_option_args() checks bounds on number of args assoc with an option */
- X/* legal_options() checks that options provided are a subset of a-zA-Z */
- X/* set_option() turns on option */
- X/* error_message() prints out an illegal syntax error message to stderr */
- X
- X
- Xint option_to_index (achar) char achar;
- X{
- X if (isupper(achar)) return(achar - 'A');
- X if (islower(achar)) return(achar - 'a' + 26);
- X return(NO_OPTION);
- X}
- X
- Xchar index_to_option (index) int index;
- X{
- X if (index < 26) return('A' + index);
- X return('a' + index - 26);
- X}
- X
- X
- X/* the command line arguments are parsed into Cmd when get_args returns */
- X/* successfully */
- X
- Xstatic Ptr_Cmd_Line Cmd = NIL;
- X
- Xint get_args (argc, argv, dup_error, print_msg)
- X
- X /* Returns one of NO_ARGS, ARG_ERROR, or ARGS_PRESENT */
- X
- X int argc;
- X char **argv;
- X Bool print_msg, dup_error;
- X
- X{
- X int i,j,dash_index;
- X Ptr_Cmd_Arg arg,last = NIL;
- X char echar, *optr;
- X
- X Cmd = (Ptr_Cmd_Line) malloc(sizeof(Cmd_Line));
- X Cmd -> non_dash_arg_list = NIL;
- X for (j = 0; j < MAX_OPTIONS; j++) (Cmd -> dash_options)[j] = F;
- X
- X if (argc == 1) return(NO_ARGS);
- X
- X i = 0;
- X dash_index = NO_OPTION;
- X
- X while (++i < argc) {
- X
- X /* parse arguments (i.e., anything not beginning with '-' */
- X
- X#ifdef UNIX
- X if (argv[i][0] != '-') {
- X#endif
- X#ifdef VMS
- X if ((argv[i][0] != '/') && (argv[i][0] != '-')) {
- X#endif
- X#ifdef MSDOS
- X if ((argv[i][0] != '/') && (argv[i][0] != '-')) {
- X#endif
- X arg = (Ptr_Cmd_Arg) malloc(sizeof(Cmd_Arg));
- X arg -> option = argv[i];
- X arg -> option_index = dash_index;
- X arg -> next = NIL;
- X if (last == NIL) {
- X Cmd -> non_dash_arg_list = arg;
- X last = arg;
- X }
- X else {
- X last -> next = arg;
- X last = arg;
- X }
- X continue;
- X }
- X
- X /* parse options. '-' by itself is illegal syntax */
- X
- X if (strlen(argv[i]) < 2) {
- X#ifdef UNIX
- X echar = '-';
- X#endif
- X#ifdef VMS
- X echar = '/';
- X#endif
- X#ifdef MSDOS
- X echar = '/';
- X#endif
- X goto parse_error;
- X }
- X optr = argv[i];
- X optr++;
- X while (*optr != '\0') {
- X if (NO_OPTION == (dash_index = option_to_index(*optr))) {
- X echar = *optr;
- X goto parse_error;
- X };
- X if ((Cmd -> dash_options)[dash_index] && dup_error) {
- X echar = *optr;
- X goto duplicate_error;
- X }
- X (Cmd -> dash_options)[dash_index] = T;
- X optr++;
- X }
- X
- X }
- X
- X return(ARGS_PRESENT);
- X
- X parse_error :
- X
- X if (print_msg) fprintf(stderr,"illegal option: %c\n",echar);
- X return(ARG_ERROR);
- X
- X duplicate_error:
- X
- X if (print_msg) fprintf(stderr,"duplicate option: %c\n",echar);
- X return(ARG_ERROR);
- X
- X}
- X
- X
- XBool option_present (achar) char achar;
- X{
- X return((Cmd -> dash_options)[option_to_index(achar)]);
- X}
- X
- X
- XBool any_option_present ()
- X{
- X int j;
- X for (j = 0; j < MAX_OPTIONS; j++) {
- X if ((Cmd -> dash_options)[j]) return(T);
- X }
- X return(F);
- X}
- X
- X
- Xchar * get_option_arg (i,n) int i; int n;
- X
- X /* get the nth option associated with the option whose index is 'i' */
- X
- X{
- X int count;
- X Ptr_Cmd_Arg args;
- X args = Cmd -> non_dash_arg_list;
- X count = 0;
- X while (args != NIL) {
- X if (i == args -> option_index && ++count == n) {
- X return(args -> option);
- X }
- X args = args -> next;
- X }
- X return(NIL);
- X}
- X
- X
- Xchar * option_arg (achar,n) char achar; int n;
- X{
- X return(get_option_arg(option_to_index(achar),n));
- X}
- X
- X
- Xchar * non_option_arg (n) int n;
- X{
- X return(get_option_arg(NO_OPTION,n));
- X}
- X
- X
- Xchar * non_dash_arg (n) int n;
- X
- X{
- X int count = 0;
- X Ptr_Cmd_Arg arg;
- X arg = Cmd -> non_dash_arg_list;
- X while (arg != NIL) {
- X if (++count == n) return(arg -> option);
- X arg = arg -> next;
- X }
- X return(NIL);
- X}
- X
- Xprint_args ()
- X
- X /* debugging routine which prints out the Cmd structure in readable form */
- X
- X{
- X int j,i,n;
- X char *option,ochar;
- X
- X if (Cmd == NIL) {
- X printf("\n\nNo arguments\n\n");
- X return;
- X }
- X
- X printf("\n\narguments not associated with options: ");
- X n = 1;
- X while (T) {
- X if (NIL == (option = non_option_arg(n++))) break;
- X printf("%s ",option);
- X }
- X printf("\n");
- X
- X printf("\n\noptions and their arguments:\n\n");
- X for (j = 0; j < MAX_OPTIONS; j++) {
- X ochar = index_to_option(j);
- X if (option_present(ochar)) {
- X printf("%c : \t",ochar);
- X i = 1;
- X while (T) {
- X if (NIL == (option = option_arg(ochar,i++))) break;
- X printf("%s ",option);
- X }
- X printf(" \t(# is %d)",n_option_args(ochar));
- X printf("\n");
- X }
- X }
- X
- X printf("\nnumber of non-dashed args is: %d\n",n_non_dash_args());
- X printf("number of non-option args is : %d\n",n_non_option_args());
- X
- X}
- X
- X
- X#define ALL -1
- X#define NON_OPTION -2
- X
- Xint arg_counter (type) int type;
- X
- X /* general routine which counts arguments */
- X /* if type isn't ALL or NON_OPTION then type is an index of an option */
- X
- X{
- X int index,count;
- X Ptr_Cmd_Arg arg;
- X arg = Cmd -> non_dash_arg_list;
- X count = 0;
- X index = (type == NON_OPTION) ? NO_OPTION : type;
- X while (arg != NIL) {
- X if (type == ALL) {
- X count++;
- X }
- X else if (arg -> option_index == index) count++;
- X arg = arg -> next;
- X }
- X return(count);
- X}
- X
- Xint n_option_args (achar) char achar;
- X{
- X return(arg_counter(option_to_index(achar)));
- X}
- X
- Xint n_non_option_args ()
- X{
- X return(arg_counter(NON_OPTION));
- X}
- X
- Xint n_non_dash_args ()
- X{
- X return(arg_counter(ALL));
- X}
- X
- X
- Xset_option (achar) char achar;
- X{
- X (Cmd -> dash_options)[option_to_index(achar)] = T;
- X}
- X
- X
- Xerror_message (progname, argv, i, usage)
- X char *progname; char ** argv; int i; char *usage;
- X{
- X fprintf(stderr,"\nillegal argument to %s : %s\n",progname,argv[i]);
- X if (usage) fprintf(stderr,"%s\n",usage);
- X}
- X
- X
- XBool
- Xcheck_option_args (achar,themin,themax) char achar; int themin,themax;
- X{
- X int n;
- X if (themin > themax) return(T);
- X n = n_option_args(achar);
- X return ((Bool) (n >= themin && n <= themax));
- X}
- X
- X
- Xchar legal_options (legalstring) char *legalstring;
- X
- X /* are all the options the user specified characters in legalstring? */
- X /* returns ALL_LEGAL if so, otherwise the first option not in the string */
- X
- X{
- X int j;
- X char option, *s;
- X for (j = 0; j < MAX_OPTIONS; j++) {
- X if ((Cmd -> dash_options)[j]) {
- X option = index_to_option(j);
- X s = legalstring;
- X while (T) {
- X if (*s == '\0') return(option);
- X if (*s == option) break;
- X s++;
- X }
- X }
- X }
- X return(ALL_LEGAL);
- X}
- END_OF_FILE
- if test 9032 -ne `wc -c <'./toolsdir/args.c'`; then
- echo shar: \"'./toolsdir/args.c'\" unpacked with wrong size!
- fi
- # end of './toolsdir/args.c'
- fi
- if test -f './toolsdir/menu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./toolsdir/menu.c'\"
- else
- echo shar: Extracting \"'./toolsdir/menu.c'\" \(8281 characters\)
- sed "s/^X//" >'./toolsdir/menu.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#ifdef UNIX
- X#include <varargs.h>
- X#endif
- X#ifdef VMS
- X#include <varargs.h>
- X#endif
- X#ifdef MSDOS
- X#include <stdarg.h>
- X#endif
- X#include "basics.h"
- X#include "ctools.h"
- X#include "menu.h"
- X#include "sys5.h"
- X
- X
- Xstatic char line[MAX_MENU_RESPONSE_LENGTH];
- X
- X
- Xmenu_match (
- X
- X ptr_rval,ptr_ur,prompt,casetest,isub,r_no_match,r_ambiguous,
- X#ifndef MSDOS
- X n_options,va_alist
- X#else
- X n_options
- X#endif
- X
- X )
- X
- X int *ptr_rval;
- X char **ptr_ur;
- X char *prompt;
- X int casetest;
- X int isub;
- X int r_no_match;
- X int r_ambiguous;
- X int n_options;
- X#ifdef VMS
- X va_dcl
- X#endif
- X#ifdef UNIX
- X int va_alist;
- X#endif
- X{
- X
- X char sline[MAX_MENU_RESPONSE_LENGTH];
- X char *options[MAX_MENU_OPTIONS];
- X int rvals[MAX_MENU_OPTIONS];
- X int j,found,len,optionlen,rval,compare,blankindex;
- X#ifdef VMS
- X int args_offset = 0; /* args_offset must be 0 in order for this to work */
- X#endif
- X va_list pvar;
- X
- X if (n_options > MAX_MENU_OPTIONS) return(MENU_ERROR);
- X for (j = 0; j < MAX_MENU_RESPONSE_LENGTH; j++) line[j] = ' ';
- X
- X /* grab all the menu options and return values. */
- X
- X blankindex = -1;
- X#ifdef VMS
- X va_start_1(pvar,args_offset);
- X#endif
- X#ifdef UNIX
- X va_start(pvar);
- X#endif
- X#ifdef MSDOS
- X va_start(pvar,n_options);
- X#endif
- X
- X for (j = 0; j < n_options; j++) {
- X options[j] = va_arg(pvar,char *);
- X if (0 == strlen(options[j])) {
- X if (blankindex == -1) blankindex = j;
- X }
- X rvals[j] = va_arg(pvar,int);
- X }
- X va_end(pvar);
- X
- X try_again :
- X
- X /* get the user's response */
- X
- X printf("%s",prompt);
- X switch (rval = getline(stdin,line,MAX_MENU_RESPONSE_LENGTH)) {
- X case AT_EOF :
- X return(MENU_EOF);
- X /* break; */
- X case TOO_MANY_CHARS :
- X fprintf(stderr,"Response is too long to handle. Please try again\n");
- X goto try_again;
- X /* break; */
- X default :
- X *ptr_ur = line;
- X remove_excess_blanks(sline,line);
- X len = strlen(sline);
- X break;
- X }
- X
- X found = 0;
- X rval = MENU_NO_MATCH;
- X
- X if (all_whitespace(sline)) {
- X if (blankindex == -1) goto try_again;
- X rval = MENU_MATCH;
- X *ptr_rval = rvals[blankindex];
- X goto rtn;
- X }
- X
- X for (j = 0; j < n_options; j ++) {
- X
- X /* if what he typed in is longer than any option it can't match */
- X
- X optionlen = strlen(options[j]);
- X if (len > optionlen) continue;
- X
- X /* if we aren't matching initial substrings, the response must */
- X /* match exactly. */
- X
- X if (!isub && len != optionlen) continue;
- X
- X /* use different comparision functions depending on whether case */
- X /* is important or not. */
- X
- X compare = casetest ?
- X strncmp(sline,options[j],len) :
- X nocase_compare(sline,len,options[j],len);
- X
- X /* if we must match exactly, if we find a match exit immediately. */
- X /* if we can match on an initial substring, if we've already found */
- X /* a match then we have an ambiguity, otherwise note that we've */
- X /* matched and continue looking in case of ambiguities */
- X
- X if (0 == compare) {
- X if (!isub) {
- X found = 1;
- X *ptr_rval = rvals[j];
- X rval = MENU_MATCH;
- X break;
- X }
- X if (found && isub) {
- X rval = MENU_AMBIGUOUS;
- X break;
- X }
- X else {
- X found = 1;
- X *ptr_rval = rvals[j];
- X rval = MENU_MATCH;
- X }
- X }
- X else {
- X continue;
- X }
- X }
- X
- X rtn :
- X
- X switch (rval) {
- X case MENU_MATCH :
- X break;
- X case MENU_NO_MATCH :
- X if (r_no_match) {
- X printf("Your response does not match any option. Try again\n");
- X goto try_again;
- X }
- X break;
- X case MENU_AMBIGUOUS :
- X if (r_ambiguous) {
- X printf("Your response is ambiguous. Try again\n");
- X goto try_again;
- X }
- X break;
- X default :
- X fprintf(stderr,"Impossible case value in menu_match\n");
- X exit(-1);
- X }
- X
- X return(rval);
- X
- X}
- X
- X
- Xmenu_yes_no (prompt,allow_help) char *prompt; int allow_help;
- X
- X{
- X int menuval,rval;
- X char *response;
- X
- X redo :
- X
- X if (!allow_help) {
- X rval = menu_match (
- X &menuval,&response,
- X prompt,
- X 0,1,0,0,2,
- X "Yes",MENU_YES,
- X "No",MENU_NO
- X );
- X }
- X else {
- X rval = menu_match (
- X &menuval,&response,
- X prompt,
- X 0,1,0,0,4,
- X "Yes",MENU_YES,
- X "No",MENU_NO,
- X "?",MENU_HELP,
- X "Help",MENU_HELP
- X );
- X }
- X switch (rval) {
- X case MENU_MATCH :
- X return(menuval);
- X /* break; */
- X case MENU_NO_MATCH :
- X fprintf(stderr,"Please type 'Yes' or 'No'...\n");
- X goto redo;
- X /* break; */
- X case MENU_EOF :
- X return(MENU_EOF);
- X /* break; */
- X default :
- X fprintf(stderr,"Fatal error: Impossible return in menu_yes_no\n");
- X exit(-1);
- X }
- X
- X return(0);
- X}
- X
- X
- Xint menu_data_help_or_abort (prompt,abortstring,ptr_response)
- X
- X char *prompt, *abortstring, **ptr_response;
- X
- X{
- X int rval,menuval;
- X rval = menu_match (
- X &menuval,ptr_response,
- X prompt,
- X 0,1,0,1,3,
- X abortstring,MENU_ABORT,
- X "?",MENU_HELP,
- X "Help",MENU_HELP
- X );
- X switch (rval) {
- X case MENU_NO_MATCH :
- X return(MENU_DATA);
- X /* break; */
- X case MENU_MATCH :
- X return(menuval);
- X /* break; */
- X case MENU_EOF :
- X return(MENU_EOF);
- X /* break; */
- X default :
- X fprintf(stderr,"Impossible return from menu_data_help_or_abort\n");
- X exit(-1);
- X }
- X
- X return(0);
- X}
- X
- X
- Xmenu_number_help_or_abort (prompt,abortstring,low,high,ptr_ival)
- X
- X char *prompt, *abortstring;
- X int low,high,*ptr_ival;
- X
- X{
- X char *response,errprompt[80],numstring[MAX_MENU_RESPONSE_LENGTH];
- X#ifdef MSDOS
- X int rval;
- X#else
- X int rval,check;
- X#endif
- X
- X#ifdef MSDOS
- X if (!(low <= high))
- X#else
- X if (!(check = (low <= high)))
- X#endif
- X nbuffconcat(errprompt,1,"Please enter a non-negative number...\n\n");
- X else
- X sprintf(errprompt,"Please enter a number between %d and %d\n\n",low,high);
- X
- X reask :
- X
- X rval = menu_data_help_or_abort(prompt,abortstring,&response);
- X switch (rval) {
- X case MENU_EOF :
- X case MENU_ABORT :
- X case MENU_HELP :
- X return(rval);
- X /* break; */
- X case MENU_DATA :
- X remove_excess_blanks(numstring,response);
- X switch (*ptr_ival = str_to_pos_int(numstring,0,MAXINT)) {
- X case -1:
- X case -2:
- X fprintf(stderr,"%s",errprompt);
- X goto reask;
- X /* break; */
- X default:
- X return(MENU_DATA);
- X /* break; */
- X }
- X }
- X
- X return(0);
- X}
- X
- X
- Xmenu_yes_no_abort_or_help (prompt,abortstring,helpallowed,return_for_yes)
- X
- X/*
- X Returns one of MENU_YES, MENU_NO, MENU_ABORT or MENU_HELP.
- X If !helpallowed, MENU_HELP will not be returned.
- X If return_for_yes is 0, hitting return will re-prompt.
- X If it is 1, hitting return is like typing yes.
- X If it is any other value, hitting return is like typing no.
- X*/
- X
- X char *prompt;
- X char *abortstring;
- X int helpallowed;
- X int return_for_yes;
- X
- X{
- X int menuval,rval;
- X char *response;
- X
- X redo :
- X
- X if (!helpallowed) {
- X rval = menu_match (
- X &menuval,&response,
- X prompt,
- X 0,1,0,0,4,
- X "Yes",MENU_YES,
- X "No",MENU_NO,
- X abortstring,MENU_ABORT,
- X "",MENU_RETURN
- X );
- X }
- X else {
- X rval = menu_match (
- X &menuval,&response,
- X prompt,
- X 0,1,0,0,6,
- X "Yes",MENU_YES,
- X "No",MENU_NO,
- X "?",MENU_HELP,
- X "Help",MENU_HELP,
- X abortstring,MENU_ABORT,
- X "",MENU_RETURN
- X );
- X }
- X switch (rval) {
- X case MENU_MATCH :
- X if (menuval != MENU_RETURN) return(menuval);
- X switch (return_for_yes) {
- X case NO_DEFAULT :
- X goto redo;
- X /* break; */
- X case DEFAULT_YES :
- X return(MENU_YES);
- X /* break; */
- X default :
- X return(MENU_NO);
- X /* break; */
- X }
- X /* break; */
- X case MENU_NO_MATCH :
- X printf("Please type 'Yes' or 'No'...\n");
- X goto redo;
- X /* break; */
- X case MENU_EOF :
- X return(MENU_EOF);
- X /* break; */
- X default :
- X fprintf(stderr,"Fatal error: Impossible return in menu_yes_no\n");
- X exit(-1);
- X }
- X
- X return(0);
- X}
- END_OF_FILE
- if test 8281 -ne `wc -c <'./toolsdir/menu.c'`; then
- echo shar: \"'./toolsdir/menu.c'\" unpacked with wrong size!
- fi
- # end of './toolsdir/menu.c'
- fi
- if test -f './toolsdir/menu.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./toolsdir/menu.h'\"
- else
- echo shar: Extracting \"'./toolsdir/menu.h'\" \(4423 characters\)
- sed "s/^X//" >'./toolsdir/menu.h' <<'END_OF_FILE'
- X/* You must include "<ctools.h>" before including this file. */
- X
- X#define MENU_EOF -1
- X#define MENU_MATCH 0
- X#define MENU_AMBIGUOUS 1
- X#define MENU_NO_MATCH 2
- X#define MENU_ERROR 3
- X#define MENU_RETURN 4
- X
- X#define MAX_MENU_OPTIONS 20
- X#define MAX_MENU_RESPONSE_LENGTH 255
- X
- X
- Xextern int menu_match();
- X
- X/* menu_match (
- X
- X int *ptr_rval,
- X char **ptr_user_response,
- X char *prompt,
- X int case_significant,
- X int initial_substring_sufficient,
- X int repeat_if_no_match,
- X int repeat_if_ambiguous,
- X int n_options,
- X char *option1, int rval1,
- X char *option2, int rval2,
- X .
- X .
- X .
- X
- X );
- X
- X Returns one of MENU_MATCH, MENU_AMBIGUOUS, MENU_NO_MATCH, and MENU_ERROR.
- X If MENU_MATCH is returned, *ptr_rval contains the value that the caller
- X asked to be returned. *ptr_user_response is what exactly what the user
- X typed in, minus the linefeed at the end.
- X
- X prompt is a character string that is printed out. A line of input is
- X then read from the terminal, stripped of excess blanks, and compared
- X with the menu items. Up to MAX_MENU_OPTIONS can be specified. Each
- X option is a character string and has an associated integer return value.
- X
- X If case_significant is not zero, the user's response will be checked
- X against the options with upper/lower case distinction.
- X If initial_substring_sufficient is not zero, then a match will occur
- X if the user's response is the same as an initial substring of an option,
- X otherwise the response must match the option exactly.
- X
- X If more than one menu option matches the response, MENU_AMBIGUOUS is
- X returned. If n_options exceeds MAX_MENU_OPTIONS or the read fails
- X MENU_ERROR is returned. If no option matches the response, MENU_NO_MATCH
- X is returned. However, if repeat_if_no_match and/or repeat_if_ambiguous
- X are non_zero, the user is prompted again until he answers correctly if
- X he answers wrongly/ambiguously, respectively.
- X
- X If "" is not specified as an option, and the user enters a blank line,
- X the routine simply prompts the user again. It is impossible to match
- X on a string of blanks (e.g., " "), because any blank line the user
- X types is considered to be "".
- X
- X If the response the user types is too long, an error message is printed
- X out and the user is asked to try again.
- X
- X*/
- X
- X
- X#define MENU_NO 0
- X#define MENU_YES 1
- X#define MENU_HELP 2
- X#define MENU_ABORT 3
- X#define MENU_DATA 4
- X
- Xextern int menu_yes_no();
- X
- X/* menu_yes_no (prompt,allow_help) char *prompt; int allow_help;
- X
- X returns one of MENU_NO, MENU_YES or, if help is allowed,
- X MENU_HELP. Help can be obtained via "?" or any initial
- X substring of "Help", case independently. Returns MENU_EOF
- X if end of file encountered when reading.
- X
- X Yes or no can be obtained via any case independent initial
- X substring of "Yes" or "No" respectively.
- X
- X*/
- X
- X
- X#define DEFAULT_YES 0
- X#define DEFAULT_NO 1
- X#define NO_DEFAULT 2
- X
- Xextern int menu_yes_no_abort_or_help ();
- X
- X/* menu_yes_no_abort_or_help (prompt,abortstring,helpallowed,return_for_yes)
- X
- X char *prompt, *abortstring;
- X int helpallowed;
- X int return_for_yes;
- X
- X Returns one of MENU_YES, MENU_NO, MENU_ABORT, MENU_HELP or MENU_EOF.
- X If !helpallowed, MENU_HELP will not be returned.
- X If return_for_yes is DEFAULT_NO, hitting return will re-prompt.
- X If it is DEFAULT_YES, hitting return is like typing yes.
- X If it is any other value, hitting return is like typing no.
- X
- X*/
- X
- Xextern int menu_data_help_or_abort ();
- X
- X/*
- X
- Xextern int menu_data_help_or_abort (prompt,abortstring,ptr_response)
- X
- X char *prompt, *abortstring, **ptr_response;
- X
- X Returns either MENU_ABORT, MENU_HELP or MENU_DATA. If MENU_DATA is
- X returned, *response contains the user's response. MENU_HELP is
- X returned in the user types in "?" or any initial substring of "Help"
- X (case independently).
- X
- X*/
- X
- X
- Xextern int menu_number_help_or_abort ();
- X
- X/*
- Xmenu_number_help_or_abort (prompt,abortstring,low,high,ptr_ival)
- X
- X char *prompt; *abortstring;
- X int low,high,*ptr_ival;
- X
- X Returns either MENU_DATA, MENU_ABORT, MENU_HELP or MENU_EOF.
- X If low > high any number will be considered valid, otherwise the
- X range is checked, inclusivewise. If MENU_DATA is returned, *ptr_ival
- X contains the number entered.
- X
- X At the moment number can only be non-negative.
- X*/
- END_OF_FILE
- if test 4423 -ne `wc -c <'./toolsdir/menu.h'`; then
- echo shar: \"'./toolsdir/menu.h'\" unpacked with wrong size!
- fi
- # end of './toolsdir/menu.h'
- fi
- if test -f './update.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./update.c'\"
- else
- echo shar: Extracting \"'./update.c'\" \(6171 characters\)
- sed "s/^X//" >'./update.c' <<'END_OF_FILE'
- X/* update.c */
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#ifdef TMC
- X#include <ctools.h>
- X#else
- X#include "ctools.h"
- X#endif
- X#include "args.h"
- X#include "menu.h"
- X#include "mem.h"
- X
- X#include "rolofilz.h"
- X#include "rolodefs.h"
- X#include "datadef.h"
- X#include "choices.h"
- X
- X#define index strchr
- X
- X
- Xchar *get_new_value ()
- X{
- X char buffer[200];
- X int rval;
- X switch (rval = getline(stdin,buffer,199)) {
- X case AT_EOF :
- X user_eof();
- X break;
- X case TOO_MANY_CHARS :
- X fprintf(stderr,"Line too long, truncated...\n");
- X sleep(1);
- X break;
- X default :
- X if ('\\' == *buffer && rval == 1) return(0);
- X break;
- X }
- X return(copystr(buffer));
- X}
- X
- X
- XPtr_Rolo_Entry copy_entry (lentry) Ptr_Rolo_Entry lentry;
- X{
- X Ptr_Rolo_Entry new_entry;
- X int j,n;
- X char **otherfields;
- X
- X new_entry = (Ptr_Rolo_Entry) rolo_emalloc(sizeof(Rolo_Entry));
- X
- X /* copy the basic fields, but get a new timestamp */
- X
- X for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- X set_basic_rolo_field(j,new_entry,copystr(get_basic_rolo_field(j,lentry)));
- X }
- X set_basic_rolo_field(N_BASIC_FIELDS - 1,new_entry,timestring());
- X
- X /* copy the user-defined fields, if necessary */
- X
- X set_n_others(new_entry,n = get_n_others(lentry));
- X if (n > 0) {
- X otherfields = (char **) rolo_emalloc(n * sizeof(char *));
- X new_entry -> other_fields = otherfields;
- X for (j = 0; j < n; j++) {
- X set_other_field(j,new_entry,copystr(get_other_field(j,lentry)));
- X }
- X }
- X else new_entry -> other_fields = 0;
- X
- X return(new_entry);
- X
- X}
- X
- X
- Xrolo_update_mode (rlink) Ptr_Rolo_List rlink;
- X
- X/* Update the fields of an entry. The user is not allowed to modify the */
- X/* timestamp field. */
- X
- X{
- X int rval,menuval,findex,updated,newlen,n,nfields,j,name_changed;
- X char *response,*s,*newfield,*newval,*other, **others;
- X Ptr_Rolo_Entry lentry,old_entry;
- X
- X if(read_only)
- X {
- X printf("Readonly mode: Updates not allowed.\n");
- X sleep(2);
- X return(1);
- X }
- X
- X cancel_update :
- X
- X lentry = copy_entry(old_entry = get_entry(rlink));
- X
- X updated = 0;
- X name_changed = 0;
- X
- X redisplay :
- X
- X display_entry_for_update(updated ? lentry : old_entry);
- X nfields = (N_BASIC_FIELDS - 1) + get_n_others(lentry);
- X
- X reask :
- X
- X cathelpfile(UPDATEMENU,(char *)NULL,0);
- X
- X rval = menu_match (
- X &menuval,&response,
- X ": ",
- X 0,1,0,1,4,
- X "\\",U_ABORT,
- X "?",U_HELP,
- X "Help",U_HELP,
- X "",U_END_UPDATE
- X );
- X
- X switch (rval) {
- X
- X case MENU_MATCH :
- X
- X switch (menuval) {
- X
- X case U_HELP :
- X cathelpfile(UPDATEHELP,"updating",1);
- X any_char_to_continue();
- X clear_the_screen();
- X goto redisplay;
- X
- X case U_ABORT :
- X if (updated) {
- X printf("Previous updates to fields in this entry ignored\n");
- X }
- X return(0);
- X /* break; */
- X
- X case U_END_UPDATE :
- X if (!updated) goto reask;
- X display_entry(lentry);
- X if (MENU_YES == rolo_menu_yes_no (
- X "Confirm Update? ",DEFAULT_YES,1,
- X CONFIRMHELP,"confirming update"
- X )) {
- X printf("Update confirmed\n");
- X sleep(1);
- X set_entry(rlink,lentry);
- X if (name_changed) {
- X rolo_delete(rlink);
- X rolo_insert(rlink,compare_links);
- X }
- X changed = 1;
- X return(0);
- X }
- X else {
- X printf("Updates ignored...\n");
- X sleep(1);
- X updated = 0;
- X goto cancel_update;
- X }
- X /* break; */
- X
- X }
- X break;
- X
- X case MENU_NO_MATCH :
- X
- X /* check that the response is an integer within range */
- X
- X findex = str_to_pos_int(response,1,nfields+1);
- X if (findex < 0) {
- X printf("Not a valid number...Please try again\n");
- X goto reask;
- X }
- X findex--;
- X
- X /* we can either be updating a standard field or a user-defined field */
- X /* or adding a new field */
- X
- X if (findex < N_BASIC_FIELDS - 1) {
- X name_changed = (findex == 0);
- X printf("Updating '%s'\n",Field_Names[findex]);
- X printf("Old value: %s\n",get_basic_rolo_field(findex,lentry));
- X printf("New value: ");
- X if (0 == (newval = copystr(get_new_value()))) break;
- X set_basic_rolo_field(findex,lentry,newval);
- X updated = 1;
- X }
- X else if (findex != nfields) {
- X findex -= N_BASIC_FIELDS - 1;
- X printf("Updating \'");
- X s = other = get_other_field(findex,lentry);
- X while (*s != ':') putc(*s++,stdout);
- X printf("\' field\n");
- X printf("Old value: %s\n",++s);
- X printf("New value: ");
- X if (0 == (newval = copystr(get_new_value()))) break;
- X if (strlen(newval) == 0) {
- X for (j = findex; j < get_n_others(lentry); j++) {
- X set_other_field(j,lentry,get_other_field(j+1,lentry));
- X }
- X set_n_others(lentry,get_n_others(lentry) - 1);
- X }
- X else {
- X *s = '\0';
- X newlen = strlen(other) + strlen(newval) + 2;
- X newfield = rolo_emalloc(newlen);
- X nbuffconcat(newfield,3,other," ",newval);
- X set_other_field(findex,lentry,newfield);
- X }
- X updated = 1;
- X }
- X else {
- X loop:
- X printf("New field (<name>: <value>): ");
- X if (0 == (newfield = copystr(get_new_value()))) break;
- X if (0 == (char *)index(newfield,':')) {
- X fprintf(stderr,"No field name. Use a ':'...\n");
- X goto loop;
- X }
- X n = get_n_others(lentry);
- X set_n_others(lentry,n + 1);
- X others = (char **) rolo_emalloc((n + 1) * sizeof(char *));
- X for (j = 0; j < n; j++) others[j] = get_other_field(j,lentry);
- X others[n] = newfield;
- X lentry -> other_fields = others;
- X updated = 1;
- X }
- X break;
- X
- X case MENU_EOF :
- X user_eof();
- X break;
- X
- X default :
- X fprintf(stderr,"Impossible return from update menu_match\n");
- X save_and_exit(-1);
- X break;
- X
- X }
- X
- X goto redisplay;
- X
- X}
- END_OF_FILE
- if test 6171 -ne `wc -c <'./update.c'`; then
- echo shar: \"'./update.c'\" unpacked with wrong size!
- fi
- # end of './update.c'
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-